# 导入必要的模块
import os
import json
import logging
from typing import List, Optional
from datetime import datetime
from pathlib import Path

# 导入FastAPI相关模块
from fastapi import APIRouter, HTTPException, Depends
from pydantic import BaseModel, Field
from sqlalchemy.orm import Session

# 导入会话历史管理模块
from app.core.memory.memory_manager import get_session_history
from app.configs.settings import get_settings
# 导入数据库相关模块
from app.configs.database import get_db
from app.services.conversation_service import ConversationService
from app.services.hybrid_conversation_service import HybridConversationService
# 导入认证相关模块
from app.api.endpoints.auth import get_current_user
from app.models import User, Conversation, Message

# 创建API路由器实例
router = APIRouter()

# 配置日志
logger = logging.getLogger(__name__)

# 获取设置
settings = get_settings()

# 会话历史文件目录
history_dir = Path("./data/chat_history")
history_dir.mkdir(parents=True, exist_ok=True)

# 定义会话信息模型
class ConversationInfo(BaseModel):
    id: int  # 对话的主键ID
    conversation_id: str
    title: str
    created_at: str
    updated_at: str
    message_count: int

# 定义更新会话标题请求模型
class UpdateTitleRequest(BaseModel):
    title: str

# 定义消息反馈请求模型
class MessageFeedbackRequest(BaseModel):
    feedback: int = Field(..., ge=-1, le=1, description="消息反馈 (1: 好评, -1: 差评, 0: 无反馈)")

# 定义消息响应模型
class MessageInfo(BaseModel):
    id: int
    message_id: str
    role: str
    content: str
    created_at: str
    token_count: Optional[int] = None
    model_name: Optional[str] = None
    temperature: Optional[str] = None
    feedback: Optional[int] = None
    thinking_process: Optional[dict] = None  # 新增：思考过程数据

# 定义反馈更新请求模型
class FeedbackUpdateRequest(BaseModel):
    feedback: int = Field(..., ge=-1, le=1, description="反馈值：-1(不好)，0(默认)，1(很好)")

def get_conversation_metadata(conversation_id: str) -> Optional[dict]:
    """获取会话元数据"""
    file_path = history_dir / f"{conversation_id}.json"
    if not file_path.exists():
        return None
    
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            data = json.load(f)
        
        # 计算消息数量
        message_count = len(data.get('messages', []))
        
        # 获取创建和更新时间
        created_at = data.get('created_at', datetime.now().isoformat())
        updated_at = data.get('updated_at', datetime.now().isoformat())
        
        # 生成标题（使用第一条用户消息的前30个字符）
        title = "新对话"
        messages = data.get('messages', [])
        for msg in messages:
            if msg.get('type') == 'human':
                content = msg.get('data', {}).get('content', '')
                if content:
                    title = content[:30] + ('...' if len(content) > 30 else '')
                    break
        
        return {
            'id': -1,  # 文件系统数据没有主键ID，使用-1表示
            'conversation_id': conversation_id,
            'title': title,
            'created_at': created_at,
            'updated_at': updated_at,
            'message_count': message_count
        }
    except Exception as e:
        print(f"Error reading conversation metadata for {conversation_id}: {e}")
        return None

@router.get("/", response_model=List[ConversationInfo])
def get_conversations(db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
    """获取当前用户的会话列表"""
    try:
        # 从数据库获取当前用户的对话
        service = HybridConversationService(db)
        conversations = service.get_user_conversations(str(current_user.user_id))

        
        if conversations:
            return [
                ConversationInfo(
                    id=conv.id,  # 添加主键ID
                    conversation_id=str(conv.conversation_id),
                    title=str(conv.title),
                    created_at=conv.created_at.isoformat(),
                    updated_at=conv.updated_at.isoformat(),
                    message_count=len(conv.messages)
                )
                for conv in conversations
            ]
        else:
            # 回退到文件系统
            conversations = []
            
            # 遍历历史文件目录
            for file_path in history_dir.glob("*.json"):
                conversation_id = file_path.stem
                metadata = get_conversation_metadata(conversation_id)
                if metadata:
                    conversations.append(ConversationInfo(**metadata))
            
            # 按更新时间倒序排列
            conversations.sort(key=lambda x: x.updated_at, reverse=True)
            return conversations
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取会话列表失败: {str(e)}")

@router.delete("/{conversation_id}")
def delete_conversation(conversation_id: str, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
    """删除指定会话"""
    try:
        # 验证对话是否属于当前用户
        service = HybridConversationService(db)
        conversation = service.get_conversation(conversation_id)
        
        if conversation is None:
            # 对话不存在，尝试从文件系统删除
            file_path = history_dir / f"{conversation_id}.json"
            if not file_path.exists():
                raise HTTPException(status_code=404, detail="会话不存在")
            
            file_path.unlink()  # 删除文件
            return {"message": "会话删除成功", "conversation_id": conversation_id}
        
        # 验证权限
        if str(conversation.user_id) != str(current_user.user_id):
            raise HTTPException(status_code=403, detail="无权限删除此对话")
        
        # 使用混合删除对话（同时删除 MySQL 和向量数据库中的数据）
        success = service.delete_conversation_hybrid(conversation_id)
        
        if success:
            return {"message": "会话删除成功", "conversation_id": conversation_id}
        else:
            raise HTTPException(status_code=500, detail="删除对话失败")
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"删除会话失败: {str(e)}")

@router.patch("/{conversation_id}")
def update_conversation_title(conversation_id: str, request: UpdateTitleRequest, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
    """更新会话标题"""
    try:
        # 验证对话是否属于当前用户
        service = HybridConversationService(db)
        conversation = service.get_conversation(conversation_id)
        if conversation is not None and str(conversation.user_id) != str(current_user.user_id):
            raise HTTPException(status_code=403, detail="无权限修改此对话")
        
        # 使用混合更新对话标题
        success = service.update_conversation_title_hybrid(conversation_id, request.title)
        
        if success:
            return {
                "message": "标题更新成功",
                "conversation_id": conversation_id,
                "title": request.title
            }
        else:
            # 回退到文件更新
            file_path = history_dir / f"{conversation_id}.json"
            
            if not file_path.exists():
                raise HTTPException(status_code=404, detail="会话不存在")
            
            # 读取现有数据
            with open(file_path, 'r', encoding='utf-8') as f:
                data = json.load(f)
            
            # 更新标题和时间戳
            data['title'] = request.title
            data['updated_at'] = datetime.now().isoformat()
            
            # 写回文件
            with open(file_path, 'w', encoding='utf-8') as f:
                json.dump(data, f, ensure_ascii=False, indent=2)
            
            return {
                "message": "标题更新成功",
                "conversation_id": conversation_id,
                "title": request.title
            }
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"更新标题失败: {str(e)}")

@router.get("/{conversation_id}/messages", response_model=List[MessageInfo])
def get_conversation_messages(conversation_id: str, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
    """根据会话conversation_id获取消息列表"""
    try:
        service = HybridConversationService(db)

        # 根据conversation_id UUID获取对话
        conversation = db.query(Conversation).filter(Conversation.conversation_id == conversation_id).first()
        if not conversation:
            raise HTTPException(status_code=404, detail="会话不存在")

        # 验证对话是否属于当前用户
        if str(conversation.user_id) != str(current_user.user_id):
            raise HTTPException(status_code=403, detail="无权限访问此对话")

        # 使用混合服务获取消息列表（包含完整内容）
        messages = service.get_conversation_messages_hybrid(
            conversation_id=conversation_id,
            include_content=True  # 包含完整内容
        )

        # 获取消息的思考过程数据
        logger.info(f"🔍 [API] 开始处理 {len(messages)} 条消息，获取思考过程数据")
        result_messages = []

        for msg in messages:
            thinking_process = None
            message_id = msg.get("message_id")
            role = msg.get("role")

            logger.info(f"🔍 [API] 处理消息: {message_id}, 角色: {role}")

            # 如果是assistant消息，尝试获取思考过程
            if role == "assistant" and message_id:
                logger.info(f"🔍 [API] 这是assistant消息，尝试获取思考过程...")
                try:
                    # 从数据库获取消息的元数据
                    from app.models import Message
                    db_message = db.query(Message).filter(
                        Message.message_id == message_id
                    ).first()

                    if db_message:
                        logger.info(f"✅ [API] 在数据库中找到消息，元数据长度: {len(db_message.message_metadata or '')}")

                        if db_message.message_metadata:
                            metadata = db_message.get_metadata()
                            thinking_process = metadata.get("thinking_process")

                            if thinking_process:
                                logger.info(f"✅ [API] 成功获取思考过程数据，迭代数: {thinking_process.get('total_iterations')}")
                            else:
                                logger.warning(f"❌ [API] 元数据中没有thinking_process字段")
                        else:
                            logger.warning(f"❌ [API] 消息没有元数据")
                    else:
                        logger.warning(f"❌ [API] 数据库中找不到消息: {message_id}")

                except Exception as e:
                    logger.error(f"❌ [API] 获取思考过程失败: {e}")
            else:
                logger.info(f"🔍 [API] 跳过非assistant消息")

            result_messages.append(MessageInfo(
                id=msg.get("id"),
                message_id=message_id,
                role=role,
                content=msg.get("content"),  # 从向量数据库获取的完整内容
                created_at=msg.get("created_at"),
                token_count=None,  # 暂时不计算token
                model_name=msg.get("model_name"),
                temperature=msg.get("temperature"),
                feedback=msg.get("feedback", 0),
                thinking_process=thinking_process  # 包含思考过程数据
            ))

            logger.info(f"✅ [API] 消息处理完成，thinking_process: {thinking_process is not None}")

        logger.info(f"✅ [API] 所有消息处理完成，返回 {len(result_messages)} 条消息")

        return result_messages
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取消息列表失败: {str(e)}")

@router.patch("/messages/{message_id}/feedback")
def update_message_feedback(message_id: str, request: FeedbackUpdateRequest, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
    """更新消息反馈"""
    try:
        # 根据message_id查找消息
        message = db.query(Message).filter(Message.message_id == message_id).first()
        if not message:
            raise HTTPException(status_code=404, detail="消息不存在")
        
        # 降低权限验证 - 允许用户修改消息反馈（可选验证）
        conversation = db.query(Conversation).filter(Conversation.conversation_id == message.conversation_id).first()
        if not conversation:
            raise HTTPException(status_code=404, detail="对话不存在")

        # 注释掉严格的用户权限检查，允许更灵活的反馈修改
        # if str(conversation.user_id) != str(current_user.user_id):
        #     raise HTTPException(status_code=403, detail="无权限修改此消息的反馈")

        # 可选：添加日志记录反馈修改操作
        logger.info(f"用户 {current_user.user_id} 修改消息 {message_id} 的反馈为 {request.feedback}")
        
        # 更新反馈值
        message.feedback = request.feedback
        db.commit()
        
        return {
            "message": "反馈更新成功",
            "message_id": message_id,
            "feedback": request.feedback
        }
        
    except HTTPException:
        raise
    except Exception as e:
        db.rollback()
        raise HTTPException(status_code=500, detail=f"更新反馈失败: {str(e)}")